op {
  graph_op_name: "UniformQuantizedConvolution"
  visibility: HIDDEN
  in_arg {
    name: "lhs"
    description: <<END
Must be a quantized tensor, rank >= 3.
END
  }
  in_arg {
    name: "rhs"
    description: <<END
Must be a quantized tensor, same rank as `lhs`.
END
  }
  in_arg {
    name: "lhs_scales"
    description: <<END
The float value(s) used as scale factors when quantizing the original data that `lhs` represents.
Must be a scalar `Tensor` (`lhs` supports only per-tensor quantization).
END
  }
  in_arg {
    name: "lhs_zero_points"
    description: <<END
The int32 value(s) used as zero points when quantizing original data that `lhs` represents.
Same shape condition as `lhs_scales`.
END
  }
  in_arg {
    name: "rhs_scales"
    description: <<END
The float value(s) used as scale factors when quantizing the original data that `rhs` represents.
Must be a scalar `Tensor` for per-tensor quantization,
or 1D `Tensor` of size `rhs.dim_size(kernel_output_feature_dimension)`, for per-channel quantization.
END
  }
  in_arg {
    name: "rhs_zero_points"
    description: <<END
The int32 value(s) used as zero points when quantizing original data that `rhs` represents.
Same shape condition as `rhs_scales`.
END
  }
  in_arg {
    name: "output_scales"
    description: <<END
The float value(s) to use as scale factors when quantizing original data that `output` represents.
Must be a scalar `Tensor` for per-tensor quantization,
or 1D `Tensor` of size `rhs.dim_size(kernel_output_feature_dimension)`
- which is equal to `output.dim_size(output_feature_dimension)`,
for per-channel quantization.
If `rhs` is per-tensor quantized, output must be also per-tensor quantized.
This means that if `rhs_scales` and `rhs_zero_points` are scalar `Tensor`s, `output_scales` and `output_zero_points` must be scalar `Tensor`s as well.
END
  }
  in_arg {
    name: "output_zero_points"
    description: <<END
The int32 value(s) used as zero points when quantizing original data that output represents.
Same shape condition as `output_scales`.
END
  }
  out_arg {
    name: "output"
    description: <<END
The output quantized tensor of `Tout`, same rank as `lhs` and `rhs`.
END
  }
  attr {
    name: "Tin"
    description: <<END
The type of `lhs` and `rhs` input `Tensor`.
END
  }
  attr {
    name: "Tout"
    description: <<END
The type of `output` `Tensor`.
END
  }
  attr {
    name: "window_strides"
    description: <<END
The stride of the sliding window for each spatial dimension of `lhs`.
Must be an empty list (default) or a list of size (number of spatial dimensions).
If an empty list is provided, the stride for each spatial dimension is set to 1.
END
  }
  attr {
    name: "padding"
    description: <<END
string from: `"SAME"`, `"VALID"`, or `"EXPLICIT"`, indicating the type of padding algorithm to use.
END
  }
  attr {
    name: "explicit_padding"
    description: <<END
If `padding` is `"EXPLICIT"`, must be set as a list indicating
the explicit paddings at the start and end of each `lhs` spatial dimension.
Otherwise, this must be empty.

(If used,) Must be a list of size `2 * (number of lhs spatial dimensions)`,
where `(explicit_padding[2 * i], explicit_padding[2 * i + 1])` indicates
`(start_padding, end_padding)` of `spatial_dimensions[i]`.
END
  }
  attr {
    name: "lhs_dilation"
    description: <<END
The dilation factor to apply in each spatial dimension of `lhs`.
Must be an empty list (default) or a list of size (number of `lhs` spatial dimensions).
If empty list, the dilation for each `lhs` spatial dimension is set to 1.
END
  }
  attr {
    name: "rhs_dilation"
    description: <<END
The dilation factor to apply in each spatial dimension of `rhs`.
Must be an empty list (default) or a list of size (number of `rhs` spatial dimensions).
If empty list, the dilation for each `rhs` spatial dimension is set to 1.
END
  }
  attr {
    name: "batch_group_count"
    description: <<END
The number of batch groups. Used for grouped filters.
Must be a divisor of `output_feature`.
END
  }
  attr {
    name: "feature_group_count"
    description: <<END
The number of feature groups. Used for grouped convolutions.
Must be a divisor of both `lhs_feature` and `output_feature`.
END
  }
  attr {
    name: "dimension_numbers"
    description: <<END
Structure of dimension information for the convolution op.
Must be an empty string (default) or a serialized string of `tensorflow.UniformQuantizedConvolutionDimensionNumbersAttr` proto.
If empty string, the default is `("NCHW", "OIHW", "NCHW")` (for a 2D convolution).
END
  }
  attr {
    name: "lhs_quantization_axis"
    description: <<END
Indicates the dimension index of the tensor where per-axis quantization is applied for the slices along that dimension.
If set to -1 (default), this indicates per-tensor quantization.
For the `lhs`, only per-tensor quantization is supported.
Thus, this must be set to -1.
Other values will raise error at OpKernel construction.
END
  }
  attr {
    name: "lhs_quantization_min_val"
    description: <<END
The min value of the quantized data stored in `lhs`.
For example, if `Tin` is `qint8`, this must be set to -127 if narrow range quantized or -128 if not.
END
  }
  attr {
    name: "lhs_quantization_max_val"
    description: <<END
The max value of the quantized data stored in `lhs`.
For example, if `Tin` is `qint8`, this must be set to 127.
END
  }
  attr {
    name: "rhs_quantization_axis"
    description: <<END
Indicates the dimension index of the tensor where per-axis quantization is applied for the slices along that dimension.
If set to -1 (default), this indicates per-tensor quantization.
For the `rhs`, only per-tensor quantization
or per-channel quantization along `kernel_output_feature_dimension` is supported.
Thus, this must be set to -1 or `dimension_numbers.kernel_output_feature_dimension`.
Other values will raise error at OpKernel construction.
END
  }
  attr {
    name: "rhs_quantization_min_val"
    description: <<END
The min value of the quantized data stored in `rhs`.
For example, if `Tin` is `qint8`, this must be set to -127 if narrow range quantized or -128 if not.
END
  }
  attr {
    name: "rhs_quantization_max_val"
    description: <<END
The max value of the quantized data stored in `rhs`.
For example, if `Tin` is `qint8`, this must be set to 127.
END
  }
  attr {
    name: "output_quantization_axis"
    description: <<END
Indicates the dimension index of the tensor where per-axis quantization is applied for the slices along that dimension.
If set to -1 (default), this indicates per-tensor quantization.
For the `output`, only per-tensor quantization or per-channel quantization along `output_feature_dimension` is supported.
Thus, this must be set to -1 or `dimension_numbers.output_feature_dimension`.
Other values will raise error at OpKernel construction.
END
  }
  attr {
    name: "output_quantization_min_val"
    description: <<END
The min value of the quantized data stored in `output`.
For example, if  `Tout` is `qint8`, this must be set to -127 if narrow range quantized or -128 if not.
END
  }
  attr {
    name: "output_quantization_max_val"
    description: <<END
The max value of the quantized data stored in `output`.
For example, if `Tout` is `qint8`, this must be set to 127.
END
  }
  summary: "Perform quantized convolution of quantized Tensor `lhs` and quantized Tensor `rhs`. to make quantized `output`."
  description: <<END
Given quantized `lhs` and quantized `rhs`, performs quantized dot on `lhs` and `rhs` to make quantized `output`.

`lhs` and `rhs` must be Tensors of same rank, and meet following shape conditions.
- `lhs_feature` % `feature_group_count` == 0
- `lhs_feature` % `rhs_input_feature` == 0
- `lhs_feature` / `feature_group_count` == `rhs_input_feature`
- `rhs_output_feature` % `feature_group_count` == 0
- `lhs_batch` % `batch_group_count` == 0
- `rhs_output_feature` % `batch_group_count` == 0

`lhs` and `rhs` must be quantized Tensor, where data value is quantized using the formula:
```
quantized_data = clip(original_data / scale + zero_point, quantization_min_val, quantization_max_val)
```
`output` is also quantized, using the same formula.
If `rhs` is per-tensor quantized, `output` must be also per-tensor quantized.
END
}
